<?php
/* Configuration */
$irc_servers = array("irc.infinityirc.com", "irc.me.uk");
$bnc_servers = array("core.geekbouncer.co.uk", "atom.geekbouncer.co.uk");
$nickserv = array("irc.infinityirc.com" => "");
$config['irc-nick'] = "GeekBouncerDev";
$config['irc-user'] = "bot";
$config['irc-real'] = "GeekBouncer.co.uk Bot";
$config['bnc-user'] = "bot";
$config['bnc-pass'] = "password";
$config['port-irc'] = 6667;
$config['port-bnc'] = 1337;
$config['chan-request'] = "#GeekBouncer";
$config['chan-control'] = "#GeekBouncer.dev";
$config['chan-log'] = "#GeekBouncer.dev";
$config['server-control'] = "irc.infinityirc.com";
$config['mysql-host'] = "localhost";
$config['mysql-user'] = "";
$config['mysql-pass'] = "";
$config['mysql-db'] = "";
$config['mailpass'] = ""; /* Set the gmail smtp password here */
$banned_servers = array(
	"irc.allnetwork.org" => "This network is suspended due to user abuse",
	"irc.test.com" => "Test banned server"
);

/* Functions */
function validate_email($email) {
	$email = filter_var($email, FILTER_SANITIZE_EMAIL);
	
	if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
		return TRUE;
	} else {
		return FALSE;
	}
}

function validate_server($server) {
	//Get the server IP
	$server_ip = gethostbyname($server);
	
	if ($server_ip == FALSE) {
		//Invalid DNS entry
		return FALSE;
	} else {
		//Valid DNS entry
		
		//Check that the IP is valid
		if (filter_var($server_ip, FILTER_VALIDATE_IP)) {
			//IP is valid
			return TRUE;
		} else {
			//IP is invalid
			return FALSE;
		}
	}
}

function validate_port($port) {
	//Define the options array
	$options = array(
		"options" => array(
			"min_range" => 1,
			"max_range" => 65535
		)
	);
	
	if (filter_var(str_replace("+", "", $port), FILTER_VALIDATE_INT, $options)) {
		return TRUE;
	} else {
		return FALSE;
	}
}

function errorlog($error) {
	global $sockets, $config;
	
	//Send the error message
	socket_write($sockets[$config['server-control']], "PRIVMSG ".$config['chan-log']." :[\002Error\002] ".$error."\n");
}

function bot_mysql_connect() {
	global $mysql, $config;
	
	//Connect to the MySQL server
	$mysql = @mysql_connect($config['mysql-host'], $config['mysql-user'], $config['mysql-pass']);
	
	if (!$mysql) {
		//Failed to connect to MySQL
		
		//Log the error
		errorlog("MySQL Error: ".mysql_error());
	} else {
		//Connected to MySQL ok, select the db
		$select = @mysql_select_db($config['mysql-db'], $mysql);
		
		if (!$select) {
			//Failed to select the db
			
			//Log the error
			errorlog("MySQL Error: ".mysql_error());
		}
	}
}

function bot_mysql_close() {
	global $mysql;
	
	//Close the MySQL connection
	@mysql_close($mysql);
	
	//Set variable to null
	$mysql = NULL;
}

function bot_mysql_query($query) {
	//Perform the query
	$query = @mysql_query($query);
	
	//Check for any errors
	if (!$query) {
		errorlog("MySQL Error: ".mysql_error());
	}
	
	//Return the query variable
	return $query;
}

function get_user_info() {
	global $ex;
	
	//Explode the user info
	$user_ex1 = explode("@", $ex[0]);
	$user_ex2 = explode("!", $user_ex1[0]);
	
	//Return the details
	return array(
		"nick" => str_replace(":", "", $user_ex2[0]),
		"user" => $user_ex2[1],
		"host" => $user_ex1[1]
	);
}

function send_data($server, $cmd) {
socket_write($server, trim($cmd)."\n");
echo trim($cmd)."\n";
}

function email_user_info($user, $pass, $server, $to) {
	global $config, $sockets;
	require_once "Mail.php";
	
	//Set variables
		$subject = "Bouncer Added";
        $host = "ssl://smtp.gmail.com";
 		$username = "Bot@geekbouncer.co.uk";
        $port = "465";
        $from = "GeekBouncer Services <Bot@geekbouncer.co.uk>";
		$body = "Hi,\n\nYour bouncer has been added.\n\n Your username is $user\n\nYour password is $pass\n\n The server your BNC is on is $server.GeekBouncer.co.uk with port 1337 or 6668.\n\nThanks for using GeekBouncer.\n\nIf you need any further help, email us iYorkie@geekbouncer.co.uk or Bkil@geekbouncer.co.uk, submit a ticket at http://support.geekbouncer.co.uk or join our chat room which can be found at irc.infinityirc.com #GeekBouncer or on the web at http://geekbouncer.co.uk/request/";
	    	$headers = array ('From' => $from,
   					'To' => $to,
  					 'Subject' => $subject);
 				$smtp = Mail::factory('smtp',
   				array ('host' => $host,
     				'port' => $port,
     				'auth' => true,
     				'username' => $username,
     				'password' => $config['mailpass']));
 
 /* Send Email */
 $mail = $smtp->send($to, $headers, $body);
 
 /* Debug */
 if (PEAR::isError($mail)) {
   send_data($sockets[$config['server-control']], "PRIVMSG ".$config['chan-log']." :E-mail failed to send! Reason: ".$mail->getMessage()."\n");
  } else {
   send_data($sockets[$config['server-control']], "PRIVMSG ".$config['chan-log']." :Mail sent sucessfully for ".$user."!\n");

  }
}
/* Main Script */
//Define variables
$sockets = array();
$mysql = NULL;

//Connect to IRC servers
foreach ($irc_servers as $irc_server) {
	//Create socket
	$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
	
	//Connect to the IRC server
	socket_connect($socket, $irc_server, $config['port-irc']);
	
	//Send user details
	send_data($socket, "USER ".$config['irc-user']." 0 * :".$config['irc-real']."\n");
	send_data($socket, "NICK ".$config['irc-nick']."\n");
	
	//Join the request channel
	send_data($socket, "JOIN ".$config['chan-request']."\n");
	
	if ($irc_server == $config['server-control']) {
		//Join the control channel
		send_data($socket, "JOIN ".$config['chan-control']."\n");
	}
	
	//Identify to NickServ (if required)
	if (isset($nickserv[$irc_server])) {
		send_data($socket, "PRIVMSG NickServ :IDENTIFY ".$nickserv[$irc_server]."\n");
	}
	
	//Write the socket into the array
	$sockets[$irc_server] = $socket;
	
	//Unset the temp socket variable for use again
	unset($socket);
}

//Connect to BNC servers
foreach ($bnc_servers as $bnc_server) {
	//Create socket
	$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
	
	//Connect to the BNC server
	socket_connect($socket, $bnc_server, $config['port-bnc']);
	
	//Send auth details
	send_data($socket, "USER ".$config['bnc-user']." 0 * :".$config['bnc-user']."\n");
	send_data($socket, "PASS ".$config['bnc-user'].":".$config['bnc-pass']."\n");
	send_data($socket, "NICK ".$config['bnc-user']."\n");
	
	//Write the socket into the array
	$sockets[$bnc_server] = $socket;
	
	//Unset the temp socket variable for use again
	unset($socket);
}

//Begin the main loop
while (1) {
	//Socket work
	$raw = $sockets;
	$number = socket_select($raw, $empty, $empty, 0, 200000);
	
	if ($number > 0) {
		foreach ($raw as $socket) {
			//Read data from the socket
			$data = socket_read($socket, 512);
			
			//Explode data
			$ex = explode(" ", $data);
				foreach ($ex as &$trim) { $trim = trim($trim);}

			if ($ex[3] == ":!test") {
			send_data($socket, "PRIVMSG #GeekBouncer.dev :Yes?");
			}
			
			//Ping/Pong Replies
			if ($ex[0] == "PING") {
				send_data($socket, "PONG ".array_slice($ex, 1));
			}
			
			//Main Channel Triggers
			if ($ex[1] == "PRIVMSG" && strtolower($ex[2]) == $config['chan-request']) {
				//Source looks like the IRC channel, check that it's on an IRC socket
				foreach ($irc_servers as $irc_server) {
					if ($socket == $sockets[$irc_server]) {
						//Server is an IRC server
						if ($ex[3] == ":!request") {
							//Request trigger
							if (isset($ex[4]) && isset($ex[5]) && isset($ex[6]) && isset($ex[7])) {
								//All details are set
								
								//Check e-mail address is valid
								if (validate_email($ex[7])) {
									//E-mail address is valid
									
									//Check that the server is valid
									if (validate_server($ex[5]) && validate_port($ex[6])) {
										//Valid server
										
										if (!in_array($ex[5], $banned_servers)) {
											//Request is ok
											//Connect to MySQL
											bot_mysql_connect();
											
											//Get the users info
											$user = get_user_info();
											
											//Add the request to the database
											bot_mysql_query("INSERT INTO `request` (`username`, `server`, `port`, `email`, `nick`, `timestamp`) VALUES ('".mysql_real_escape_string($ex[4])."', '".mysql_real_escape_string($ex[5])."', '".mysql_real_escape_string($ex[6])."', '".mysql_real_escape_string($ex[7])."', '".mysql_real_escape_string($user['nick'])."', '".time()."')");
											
											//Let the user know the request was ok
											send_data($socket, "PRIVMSG ".$ex[2]." :Thank you for your request. You will recieve an e-mail from GeekBouncer with your new BNC details within \00224 hours\002. To check the status of your request use !check <username>.");
											
											//Log the new request to the control channel
											send_data($sockets[$config['server-control']], "PRIVMSG ".$config['chan-control']." :\002Request\002 by ".$user['nick']." on ".$irc_server." - Username: ".$ex[4]." / IRC Server: ".$ex[5]." / Port: ".$ex[6]." / Email: ".$ex[7]."");
											
											unset($user);
											
											//Disconnect from MySQL
											bot_mysql_close();
										} else {
											//Banned server
											send_data($socket, "PRIVMSG ".$ex[2]." :Error: Banned Server (".$banned_servers[$ex[5]].")");
										}
									} else {
										//Invalid server
										send_data($socket, "PRIVMSG ".$ex[2]." :Error: Server or Port is invalid.");
									}
								} else {
									//Invalid e-mail address
									send_data($socket, "PRIVMSG ".$ex[2]." :Error: Email address is invalid.");
								}
							} else {
								//Error: Not all details are set
								send_data($socket, "PRIVMSG ".$ex[2]." :Syntax: !request [Username] [IRC Server] [Port] [Email]");
							}
						} elseif ($ex[3] == ":!check") {
							//Check trigger
							if (isset($ex[4])) {
								//Username is set
								//Connect to MySQL
								bot_mysql_connect();
								
								//Load data for the username
								$mysql_query_check = bot_mysql_query("SELECT `status` FROM `request` WHERE `username` = '".mysql_real_escape_string($ex[4])."'");
								
								if (mysql_num_rows($mysql_query_check) != 0) {
									//User exists
									//Fetch user info to an array
									$mysql_array_check = mysql_fetch_array($mysql_query_check);
									
									if ($mysql_array_check['status'] == 0) {
										//Request is pending
										send_data($socket, "PRIVMSG ".$ex[2]." :".$ex[4].": Request is pending.");
									} elseif ($mysql_array_check['status'] == 1) {
										//Request approved
										send_data($socket, "PRIVMSG ".$ex[2]." :".$ex[4].": Request has been approved. You should have an email from GeekBouncer with your BNC details.");
									} elseif ($mysql_array_check['status'] == 2) {
										//Request denied
										send_data($socket, "PRIVMSG ".$ex[2]." :".$ex[4].": Request has been denied. Contact a member of staff for more information.");
									}
									
									unset($mysql_array_check);									
								} else {
									//User doesn't exist
									send_data($socket, "PRIVMSG ".$ex[2]." :Error: Username could not be found.");
								}
								
								unset($mysql_query_check);
								
								//Disconnect from MySQL
								bot_mysql_close();
							} else {
								//Username isn't set
								send_data($socket, "PRIVMSG ".$ex[2]." :Syntax: !check [username]");
							}
						}
						
						//Break the foreach loop
						break;
					}
				}
			}
			
			//Control triggers
			if ($ex[1] == "PRIVMSG" && $ex[2] == $config['chan-control'] && $socket == $sockets[$config['server-control']]) {
				//Message is in control channel
				if ($ex[3] == ":!global" && isset($ex[4])) {
					foreach ($irc_servers as $irc_server) {
						send_data($sockets[$irc_server], "PRIVMSG #GeekBouncer :[\002Global\002] ".array_slice($ex, 4)."");
					}
				if ($ex[3] == ":!testemail") {
				email_user_info("loluser", "lolpass", "lolatom", "iYorkie@GeekBouncer.co.uk");
					}
				
				}
			}

		}
	}	
}
?>